/*
  File:    ParseText.cpp
  Purpose: Provides functions to parse a text configuration 
           file to retrieve string and double parameters. 
		   These functions respect C++ style comments. 

  Contact: Paul Macklin
           pmacklin@math.uci.edu
		   http://math.uci.edu/~pmacklin
*/

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <fstream>

using namespace std;

char ParseDelimiterCharacter = '=';

double RetrieveDoubleParameter( char* FileName , char* ParameterName )
{
 double output = 0.0;

 fstream fs;
 fs.open( FileName , ios::in );
 
 bool Success = false;
 
 while( !fs.eof() && !Success )
 {
  char Input [2048];
  Input[0] = '\0';

  fs >> Input; 

  // these next code chunks deal with 
  // comment lines. Acceptable comment 
  // types: C++ style: /* comment */
  // of     // comment line
  
  if( strstr( Input , "/*" ) )
  {
   bool EndComment = false;
   while( !EndComment )
   { 
    char CommentInput [2048];
    fs >> CommentInput; 
    if( strstr( CommentInput , "*/" ) )
    { EndComment = true; }
   }
   
   Input[0] = '\0';
   fs >> Input;
  }  

  if( strstr( Input , "//" ) == Input )
  { 
   char c = fs.get();
   while( c != '\n' )
   { c = fs.get(); }

   Input[0] = '\0';
   fs >> Input;
  }

  // looks for the parameter name in the string
  
  if( strstr( Input , ParameterName ) == Input )
  {
   bool TrueFind = false;
  
   if( strlen( Input ) == strlen( ParameterName ) )
   { TrueFind = true; }
   if( Input[strlen(ParameterName)] == ParseDelimiterCharacter )
   { TrueFind = true; }

   if( TrueFind )
   {
    if( strlen(Input) == strlen(ParameterName) || 
	    Input[strlen(ParameterName)] == ParseDelimiterCharacter)
	{ 
     Input[0] = '\0';
     fs >> Input;	 
	}
	
	if( Input[0] == ParseDelimiterCharacter )
	{ Input[0] = ' '; }
	if( strlen( Input ) == 1 )
	{
	 Input[0] = '\0';
	 fs >> Input; 
	}
	int i = 0;
	while( !isdigit( Input[i] ) && Input[i] != '.' && Input[i] != '-' )
	{ Input[i] = ' '; i++; }
    output = strtod( Input , NULL );	
    Success = true; 
   }
  }

 }
 fs.close();
 
// cout << ParameterName  << " : " << output << endl;

 return output;
}

bool RetrieveStringParameter( char* FileName , char* ParameterName, char* TargetString )
{
 double output = 0.0;

 fstream fs;
 fs.open( FileName , ios::in );
 
 bool Success = false;
 
 while( !fs.eof() && !Success )
 {
  char Input [2048];
  Input[0] = '\0';

  fs >> Input; 

  // these next code chunks deal with 
  // comment lines. Acceptable comment 
  // types: C++ style: /* comment */
  // of     // comment line
  
  if( strstr( Input , "/*" ) )
  {
   bool EndComment = false;
   while( !EndComment )
   { 
    char CommentInput [2048];
    fs >> CommentInput; 
    if( strstr( CommentInput , "*/" ) )
    { EndComment = true; }
   }
   
   Input[0] = '\0';
   fs >> Input;
  }  

  if( strstr( Input , "//" ) == Input )
  { 
   char c = fs.get();
   while( c != '\n' )
   { c = fs.get(); }

   Input[0] = '\0';
   fs >> Input;
  }

  // looks for the parameter name in the string
  
  if( strstr( Input , ParameterName ) == Input )
  {
   bool TrueFind = false;
  
   if( strlen( Input ) == strlen( ParameterName ) )
   { TrueFind = true; }
   if( Input[strlen(ParameterName)] == ParseDelimiterCharacter )
   { TrueFind = true; }

   if( TrueFind )
   {
    if( strlen(Input) == strlen(ParameterName) || 
	    Input[strlen(ParameterName)] == ParseDelimiterCharacter)
	{ 
     Input[0] = '\0';
     fs >> Input;	 
	}
	
	if( Input[0] == ParseDelimiterCharacter )
	{ Input[0] = ' '; }
	if( strlen( Input ) == 1 )
	{
	 Input[0] = '\0';
	 fs >> Input; 
	}
	int i = 0;
	
/*
	while( !isdigit( Input[i] ) && Input[i] != '.' && Input[i] != '-' )
	{ Input[i] = ' '; i++; }
    output = strtod( Input , NULL );	
*/	
    // find the first non-whitespace character
	int Start = 0;	
	while( Input[Start] == ' ' )
	{ Start++; }
	// find the last character
	int End = Start;
	while( Input[End] != '\0' )
	{ End++; }
	
	i=0;
	
    for( int j=Start ; j <= End; j++ )
	{ TargetString[i] = Input[j]; i++; }

    Success = true; 
   }
  }

 }
 fs.close();
 
 return true;
}

